package com.ruoyi.system.controller;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.ChatResponse;
import com.ruoyi.system.domain.aiChat;
import com.ruoyi.system.service.IaiChatService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * aiChatController
 *
 * @author ruoyi
 * @date 2025-01-09
 */
@RestController
@RequestMapping("/system/aiChat")
public class AITongYiChatController extends BaseController {
    private final ChatClient chatClient;
    private final ChatMemory chatMemory;
    @Autowired
    private IaiChatService aiChatService;

    public AITongYiChatController(ChatClient chatClient, ChatMemory chatMemory) {
        this.chatClient = chatClient;
        this.chatMemory = chatMemory;
    }

    @PreAuthorize("@ss.hasPermi('system:aiChat:query')")
    @GetMapping("/listBySessionId/{sessionId}")
    @ResponseBody
    public AjaxResult getDialogsBySessionId(@PathVariable("sessionId") Long sessionId) {
        aiChat chat = new aiChat();
        chat.setSessionId(sessionId);
        List<aiChat> list = aiChatService.selectaiChatList(chat);
        return success(list);
    }

    /**
     * 查询aiChat列表
     */
//    @GetMapping("/steamChat")
//    public ChatResponse steamChat(@RequestParam String input) {
//        // 创建用户消息
//        UserMessage userMessage = new UserMessage(input);
//
//        // 将用户消息添加到对话历史中
//        chatMemory.add("conversationId", List.of(userMessage));
//
//        // 获取AI响应
//        String aiMessage = this.chatClient.prompt()
//                .user(input)
//                .advisors(a -> a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
//                .call().content();
//
//        // 提取关键词
//        List<String> keywords = extractKeywords(aiMessage);
//
//        // 根据AI生成的内容设置type属性的值
//        String type = determineType(aiMessage);
//
//        // 创建ChatResponse对象
//        ChatResponse chatResponse = new ChatResponse(input, aiMessage, keywords, type);
//
//        return chatResponse;
//    }

    //    @PreAuthorize("@ss.hasPermi('system:aiChat:steamChat')")
    @GetMapping("/steamChat")
    public ResponseEntity<ChatResponse> steamChat(@RequestParam String input) throws NoApiKeyException, InputRequiredException {
        try {
            // 创建用户消息
            UserMessage userMessage = new UserMessage(input);
            chatMemory.add("conversationId", List.of(userMessage));

            // 添加初始设定
            String initialPrompt = "你作为一名专业的代码编程专家，擅长所有的开发技能，并作为用户的编程助手。当你问你任何有关的问题时，请参考如下步骤来执行：\n" +
                    "1.请先分析提问是否和编程或项目有关，若无关，则引导用户提问编程有关的问题。\n" +
                    "2.分析用户的提问，检查用户要构建普通程序还是项目，若构建普通程序则仅需询问对应语言和需求。\n" +
                    "若用户需要构建项目，则检查缺少的关键内容（如编程语言和版本的选择、对应编程语言框架和版本的选择、对应编程语言的API风格或项目构建方式\n" +
                    "3.、对应编程语言适合的编程工具等）若缺少或未选择则依次进行询问并以列表的方式罗列出对应的内容以作参考（如列出编程语言、框架等），并且支持用户点击后直接输入，无需用户手动输入；\n" +
                    "4.当用户输入的内容无法理解，或者用户对列出的选项给出不恰当的回应时，此时需要告知用户输入无效，并重新展示选项（例如，用户可能输入了一个不存在的编程语言选项）。如果用户的项目或需求不需要编程框架或编程工具则不用提供。\n" +
                    "5.若用户需要构建前后端分离的项目则还应询问需要什么前端框架框和版本，并以列表的方式罗列出常用的框架和版本以作参考，并且支持用户点击后直接输入，无需用户手动输入；\n" +
                    "6.若用户对于其他类型的项目（如微服务架构、单体架构等）有需求，增加对整体架构设计相关的询问，以更好地贴合复杂项目的需求。\n" +
                    "7.在提供编程语言和框架版本时，对于可能存在兼容性问题的版本组合，给出简要提示，避免用户后续开发过程中遇到版本不兼容的困扰。\n" +
                    "8.前面步骤中的内容确定了之后，回答问题时，只需要提供代码，不要解释其工作原理，优先选择最高效的最标准的一个解决方案。";

            // 使用Generation类调用模型
            Generation gen = new Generation();
            GenerationParam param = GenerationParam
                    .builder()
                    .model("qwq-32b-preview")
                    .prompt(initialPrompt + "\n\nHuman: " + input + "\n\nAssistant:")
                    .build();
            GenerationResult result = gen.call(param);

            // 正确获取AI响应文本
            String aiMessage = result.getOutput().getText();
            if (aiMessage == null || aiMessage.isEmpty()) {
                throw new RuntimeException("AI响应为空");
            }

            // 提取关键词和类型
            List<String> keywords = extractKeywords(aiMessage);
            String type = determineType(aiMessage);

            // 创建响应对象
            ChatResponse chatResponse = new ChatResponse(input, aiMessage, keywords, type);

            // 打印返回的ChatResponse对象
            System.out.println("ChatResponse: " + chatResponse);

            return ResponseEntity
                    .ok()
//                    .contentType(MediaType.APPLICATION_JSON_UTF8) // 使用UTF-8编码
                    .body(chatResponse);

        } catch (Exception e) {
            // 打印错误信息
            System.out.println("Chat处理失败: " + e.getMessage());
            return ResponseEntity
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new ChatResponse(input, "处理请求时发生错误: " + e.getMessage(), null, "error"));
        }
    }

    private String determineType(String aiMessage) {
        if (aiMessage.contains("编程语言")) {
            return "编程语言";
        } else if (aiMessage.contains("框架")) {
            return "框架";
        } else if (aiMessage.contains("工具")) {
            return "工具";
        } else if (aiMessage.contains("Java") && aiMessage.contains("版本")) {
            return "语言版本";
        } else if (aiMessage.contains("Spring Boot") && aiMessage.contains("版本")) {
            return "框架版本";
        }
        // 可以根据需要添加更多的关键字检测逻辑
        return null;
    }

    private List<String> extractKeywords(String input) {
        List<String> keywords = new ArrayList<>();

//        // 从chatMemory中获取之前存储的关键字
//        List<String> existingKeywords = chatMemory.get("conversationId", 100).stream()
//                .map(Message::getContent)
//                .flatMap(content -> Arrays.stream(content.split(" "))) // 假设关键字之间用空格分隔
//                .collect(Collectors.toList());
//
//        // 当输入包含“编程语言”时，添加一系列编程语言
//        if (input.contains("编程语言") && !existingKeywords.contains("编程语言")) {
//            keywords.add("Java");
//            keywords.add("Python");
//            keywords.add("C++");
//            keywords.add("JavaScript");
//            // 可以根据需要添加更多编程语言
//        }
//
//        // 当输入包含“框架”时，添加一系列框架
//        if (input.contains("框架") && input.contains("编程语言") && !existingKeywords.contains("框架")) {
//            keywords.add("Spring Boot");
//            keywords.add("Django");
//            keywords.add("React");
//            keywords.add("Vue.js");
//            // 可以根据需要添加更多框架
//        }
//
//        // 当输入包含“编程工具”时，添加一系列编程工具
//        if (input.contains("工具") && !existingKeywords.contains("工具")) {
//            keywords.add("IntelliJ IDEA");
//            keywords.add("VSCode");
//            keywords.add("PyCharm");
//            keywords.add("WebStorm");
//            keywords.add("Eclipse");
//        }
//
//        if (input.contains("Java") && input.contains("版本")) {
////            && !existingKeywords.contains("Java")
//            keywords.add("Java 8");
//            keywords.add("Java 11");
//            keywords.add("Java 17");
//        }
//
//        if (input.contains("Spring Boot") && input.contains("版本")) {
//            keywords.add("Spring Boot 2.3.x");
//            keywords.add("Spring Boot 2.5.x");
//            keywords.add("Spring Boot 2.6.x");
//            keywords.add("Spring Boot 2.7.x");
//        }

        // 新增：检测AI生成结果中的列表内容并添加到keywords列表中
        String[] lines = input.split("\n");
        boolean inList = false;
        for (String line : lines) {
            line = line.trim();
            if (line.startsWith("供您参考：") || line.startsWith("例如：") || line.startsWith("常见的有以下几种：")) {
                inList = true;
                continue;
            }
            if (line.isEmpty()) {
                inList = false;
                continue;
            }
            if (inList) {
                keywords.add(line);
            }
        }

        return keywords;
    }

    /**
     * 查询aiChat列表
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:list')")
    @GetMapping("/list")
    public TableDataInfo list(aiChat aiChat) {
        startPage();
        List<aiChat> list = aiChatService.selectaiChatList(aiChat);
        return getDataTable(list);
    }

    /**
     * 导出aiChat列表
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:export')")
    @Log(title = "aiChat", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, aiChat aiChat) {
        List<aiChat> list = aiChatService.selectaiChatList(aiChat);
        ExcelUtil<aiChat> util = new ExcelUtil<aiChat>(aiChat.class);
        util.exportExcel(response, list, "aiChat数据");
    }

    /**
     * 获取aiChat详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(aiChatService.selectaiChatById(id));
    }

    /**
     * 新增aiChat
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:add')")
    @Log(title = "aiChat", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody aiChat aiChat) {
        return toAjax(aiChatService.insertaiChat(aiChat));
    }

    /**
     * 修改aiChat
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:edit')")
    @Log(title = "aiChat", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody aiChat aiChat) {
        return toAjax(aiChatService.updateaiChat(aiChat));
    }

    /**
     * 删除aiChat
     */
    @PreAuthorize("@ss.hasPermi('system:aiChat:remove')")
    @Log(title = "aiChat", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(aiChatService.deleteaiChatByIds(ids));
    }
}
